package com.wanglianyun.utils;

import com.wanglianyun.constant.DateTimeConstant;
import org.springframework.format.annotation.DateTimeFormat;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Description: 日期处理工具
 * java8之前可以使用SimpleDateFormat进行处理，Java8之后可以使用DateTimeFormatter
 * Copyright: Copyright (c) 2024
 * Create Time: 2024-11-18 09:26
 *
 * @author wanglianyun
 */
public class StringDataConvertUtil {

    private static final Map<String, DateTimeFormatter> map = getInitFormatters();

    private static Map<String, DateTimeFormatter> getInitFormatters() {
        Map<String, DateTimeFormatter> map = new HashMap<>();
        map.put(DateTimeConstant.DATE_DEFAULT_PATTERN, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        map.put(DateTimeConstant.DATE_TIME_DEFAULT_PATTERN, DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
        return map;
    }

    /**
     * 按照输入的格式将字符串解析为date类型
     * @param dateStr 要格式化的日期字符串 例如："2024-11-18 17:47:22"
     * @param formatStr 格式字符串 eg: "yyyy-MM-dd HH:mm:ss"
     * @return 格式化结果
     */
    public static Date parse(String dateStr, String formatStr) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatStr);
        try {
            return simpleDateFormat.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 按照输入的格式将日期类型对象格式化成日期字符串
     * @param date 日期类型对象
     * @param formatStr 格式字符串 例如："yyyy-MM-dd HH:mm:ss"
     * @return 结果
     */
    public static String format(Date date, String formatStr) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatStr);
        return simpleDateFormat.format(date);
    }

    /**
     * 计算两个日期之间相差的天数
     * @param date1 日期1
     * @param date2 日期2
     * @return 结果
     */
    public static int betweenDays(Date date1, Date date2) {
        long betweenMillisecond = Math.abs(date1.getTime() - date2.getTime());
        return (int) (betweenMillisecond / 86400000);
    }

    /**
     * 判断某个日期是否在【start, end】区间范围内
     * @param start 开始时间
     * @param end 结束时间
     * @param date 要判断的时间
     * @return 在为true，不在为false
     */
    public static boolean isBetween(Date start, Date end, Date date) {
        return date.after(start) && date.before(end);
    }

    /**
     * 获取当前日期并指定时、分、秒
     * @param hour 时
     * @param minute 分
     * @param second 秒
     * @return 时间
     */
    public static Date getDateTime(int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        // 当前时间加上一定时间
//        calendar.add(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);

        return calendar.getTime();
    }

    /**
     * 获取当前日期的前一天
     * @return 结果
     */
    public static Date getYesterday() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_YEAR, -1);

        return calendar.getTime();
    }

    /**
     * 按照输入的日期格式，将字符串解析为LocalDate类型
     * @param dateStr 要解析的字符串
     * @param pattern 格式化标准
     * @return 结果
     */
    public static LocalDate parseDate(String dateStr, String pattern) {
        DateTimeFormatter dateTimeFormatter = map.get(pattern);
        return LocalDate.parse(dateStr, dateTimeFormatter);
    }

    /**
     * 按照输入的日期格式，将LocalDate对象格式化为字符串
     * @param localDate 要格式化的LocalDate对象
     * @param pattern 格式化标准
     * @return 结果
     */
    public static String formatStr(LocalDate localDate, String pattern) {
        DateTimeFormatter dateTimeFormatter = map.get(pattern);
        return localDate.format(dateTimeFormatter);
    }

    /**
     * 按照输入的日期格式，将字符串解析为LocalDateTime格式
     * @param dateStr 要解析的字符串
     * @param pattern 格式化标准
     * @return 结果
     */
    public static LocalDateTime parseDateTime(String dateStr, String pattern) {
        DateTimeFormatter dateTimeFormatter = map.get(pattern);
        return LocalDateTime.parse(dateStr, dateTimeFormatter);
    }

    /**
     * 按照输入的日期格式，将LocalDateTime对象格式化为字符串
     * @param localDateTime 要格式化的LocalDateTime对象
     * @param pattern 格式化标准
     * @return 结果
     */
    public static String formatDateTimeStr(LocalDateTime localDateTime, String pattern) {
        DateTimeFormatter dateTimeFormatter = map.get(pattern);
        return localDateTime.format(dateTimeFormatter);
    }

    /**
     * 获取两个日期之间的天数
     * @param dateTime1 时间1
     * @param dateTime2 时间2
     * @return 结果
     */
    public static long getbetweenDays(LocalDateTime dateTime1, LocalDateTime dateTime2) {
        Duration between = Duration.between(dateTime1, dateTime2);
        return between.toDays();
    }
}
